﻿using System;
using K9Nano.Captcha;
using Microsoft.Extensions.Options;
using SkiaSharp;

namespace K9Nano.Drawing.SkiaSharp.Internals;

internal class SkiaSharpCaptchaGenerator(IOptions<CaptchaOptions> options) : ICaptchaGenerator
{
    public byte[] Generate(string code)
    {
        var width = options.Value.Width;
        var height = options.Value.Height;
        using var bitmap = new SKBitmap(width, height);
        using var canvas = new SKCanvas(bitmap);
        // 设置背景色（浅色随机）
        canvas.Clear(GetRandomLightColor());

        // 添加干扰线
        DrawNoiseLines(canvas, width, height);

        // 绘制验证码文本（带扭曲效果）
        DrawTextWithDistortion(canvas, code, width, height);

        // 添加噪点
        DrawNoisePoints(canvas, width, height);

        // 保存为PNG
        using var image = SKImage.FromBitmap(bitmap);
        using var data = image.Encode(SKEncodedImageFormat.Png, 100);
        return data.ToArray();
    }

    private static void DrawNoiseLines(SKCanvas canvas, int width, int height)
    {
        for (var i = 0; i < 10; i++)
        {
            var paint = new SKPaint
            {
                Color = GetRandomColor(),
                StrokeWidth = 1,
                IsAntialias = true
            };

            canvas.DrawLine(
                Random.Shared.Next(0, width),
                Random.Shared.Next(0, height),
                Random.Shared.Next(0, width),
                Random.Shared.Next(0, height),
                paint);
        }
    }

    private static void DrawTextWithDistortion(SKCanvas canvas, string text, int width, int height)
    {
        var charWidth = width / (float)text.Length;

        for (var i = 0; i < text.Length; i++)
        {
            // 每个字符使用随机颜色
            using var textPaint = new SKPaint
            {
                Color = GetRandomDarkColor(),
                IsAntialias = true
            };

            using var font = new SKFont(SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold), height * 0.6f);

            // 计算字符位置（基础位置）
            var x = i * charWidth + charWidth / 4;
            var y = height * 0.7f;

            // 添加随机偏移和旋转
            var offsetX = Random.Shared.Next(-5, 5);
            var offsetY = Random.Shared.Next(-5, 5);
            var rotation = Random.Shared.Next(-15, 15);

            // 保存当前画布状态
            canvas.Save();

            // 应用变换
            canvas.Translate(x + offsetX, y + offsetY);
            canvas.RotateDegrees(rotation);

            // 绘制字符
            canvas.DrawText(text[i].ToString(), 0, 0, font, textPaint);

            // 恢复画布状态
            canvas.Restore();
        }
    }

    private static void DrawNoisePoints(SKCanvas canvas, int width, int height)
    {
        for (var i = 0; i < 100; i++)
        {
            var paint = new SKPaint
            {
                Color = GetRandomColor(),
                StrokeWidth = 1,
                IsAntialias = true
            };

            canvas.DrawPoint(
                Random.Shared.Next(0, width),
                Random.Shared.Next(0, height),
                paint);
        }
    }

    private static SKColor GetRandomColor()
    {
        return new SKColor(
            (byte)Random.Shared.Next(256),
            (byte)Random.Shared.Next(256),
            (byte)Random.Shared.Next(256));
    }

    private static SKColor GetRandomLightColor()
    {
        // 生成浅色背景（RGB值都大于180）
        return new SKColor(
            (byte)Random.Shared.Next(180, 256),
            (byte)Random.Shared.Next(180, 256),
            (byte)Random.Shared.Next(180, 256));
    }

    private static SKColor GetRandomDarkColor()
    {
        // 生成深色文本（RGB值都小于180）
        return new SKColor(
            (byte)Random.Shared.Next(0, 180),
            (byte)Random.Shared.Next(0, 180),
            (byte)Random.Shared.Next(0, 180));
    }
}
